/*
 * EBP3901开发板硬件驱动实现
 * 包含所有硬件外设的底层驱动函数
 */

#include "hardware_abstraction.h"
#include "system_config.h"
#include <stdio.h>
#include <string.h>
#include <math.h>

// 私有变量
static volatile uint32_t g_system_ticks = 0;
static volatile bool g_button_states[3] = {false};
static volatile uint32_t g_button_press_time[3] = {0};

// 音符频率表
static const uint16_t note_frequencies[] = {
    262, 294, 330, 349, 392, 440, 494, 523,  // C4-C5
    554, 587, 659, 698, 784, 880, 988, 1047  // C#5-C6
};

// 旋律定义
static const uint16_t startup_melody[] = {262, 330, 392, 523, 0};
static const uint16_t hourly_melody[] = {523, 523, 523, 523, 0};
static const uint16_t warning_melody[] = {880, 0, 880, 0, 880, 0};
static const uint16_t error_melody[] = {200, 0, 200, 0, 200, 0};
static const uint16_t shutdown_melody[] = {523, 392, 330, 262, 0};

/**
 * @brief 硬件初始化
 */
void hardware_init(void)
{
    // 系统时钟初始化
    // 配置系统时钟为168MHz
    
    // 使能GPIO时钟
    // RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | 
    //                 RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN;
    
    // 使能定时器时钟
    // RCC->APB1ENR |= RCC_APB1ENR_TIM2EN | RCC_APB1ENR_TIM3EN;
    // RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
    
    // 使能UART时钟
    // RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
    // RCC->APB1ENR |= RCC_APB1ENR_UART5EN;
    
    // 使能I2C时钟
    // RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;
    
    printf("EBP3901硬件初始化完成\n");
}

/**
 * @brief GPIO初始化
 */
void gpio_init(void)
{
    // 配置超声波传感器引脚
    // GPIO_ULTRASONIC_TRIG (GPIO28) - 输出
    // GPIO_ULTRASONIC_ECHO (GPIO29) - 输入
    
    // 配置LED引脚 - 输出
    // GPIO_LED_RED (GPIO35)
    // GPIO_LED_GREEN (GPIO36) 
    // GPIO_LED_BLUE (GPIO41)
    
    // 配置按键引脚 - 输入，上拉
    // GPIO_BUTTON_FUNC (GPIO56)
    // GPIO_BUTTON_CALIB (GPIO82)
    // GPIO_BUTTON_RESET (GPIO83)
    
    // 配置蜂鸣器引脚 - PWM输出
    // GPIO_BUZZER (GPIO42)
    
    // 配置继电器引脚 - 输出
    // GPIO_RELAY (GPIO52)
    
    printf("GPIO初始化完成\n");
}

/**
 * @brief 延时函数
 */
void delay_ms(uint32_t ms)
{
    uint32_t start_tick = g_system_ticks;
    while ((g_system_ticks - start_tick) < ms) {
        // 等待
    }
}

void delay_us(uint32_t us)
{
    // 简单的微秒延时
    volatile uint32_t count = us * (CPU_FREQUENCY_MHZ / 4);
    while (count--) {
        __asm("nop");
    }
}

/**
 * @brief 超声波传感器初始化
 */
void ultrasonic_init(void)
{
    // 配置TRIG引脚为输出，初始为低电平
    // 配置ECHO引脚为输入
    // 配置定时器用于测量回响时间
    
    printf("超声波传感器初始化完成\n");
}

/**
 * @brief 获取超声波距离
 */
float ultrasonic_get_distance(void)
{
    static float last_valid_distance = 50.0f;
    
    // 发送10us触发脉冲
    // GPIO_SetBits(GPIOX, GPIO_ULTRASONIC_TRIG);
    delay_us(10);
    // GPIO_ResetBits(GPIOX, GPIO_ULTRASONIC_TRIG);
    
    // 测量回响时间
    uint32_t timeout = 30000; // 30ms超时
    uint32_t start_time = 0, end_time = 0;
    
    // 等待回响信号上升沿
    while (/*!GPIO_ReadInputDataBit(GPIOX, GPIO_ULTRASONIC_ECHO) &&*/ timeout--) {
        delay_us(1);
    }
    
    if (timeout == 0) {
        return last_valid_distance; // 超时，返回上次有效值
    }
    
    start_time = g_system_ticks * 1000; // 转换为微秒
    timeout = 30000;
    
    // 等待回响信号下降沿
    while (/*GPIO_ReadInputDataBit(GPIOX, GPIO_ULTRASONIC_ECHO) &&*/ timeout--) {
        delay_us(1);
    }
    
    if (timeout == 0) {
        return last_valid_distance; // 超时，返回上次有效值
    }
    
    end_time = g_system_ticks * 1000;
    
    // 计算距离 (声速340m/s)
    float distance = (end_time - start_time) * 0.034f / 2.0f;
    
    // 距离有效性检查
    if (distance > 2.0f && distance < 400.0f) {
        last_valid_distance = distance;
        return distance;
    }
    
    return last_valid_distance;
}

/**
 * @brief 超声波传感器校准
 */
void ultrasonic_calibrate(void)
{
    printf("开始超声波传感器校准...\n");
    
    float distances[10];
    float sum = 0;
    
    // 采集10次数据
    for (int i = 0; i < 10; i++) {
        distances[i] = ultrasonic_get_distance();
        sum += distances[i];
        delay_ms(100);
    }
    
    float average = sum / 10.0f;
    printf("校准完成，平均距离: %.1fcm\n", average);
}

/**
 * @brief OLED显示屏初始化
 */
void oled_init(void)
{
    // I2C初始化
    // 配置I2C1: SCL(GPIO5), SDA(GPIO3)
    
    // OLED初始化序列
    // 发送初始化命令到0x3C地址
    
    printf("OLED显示屏初始化完成\n");
}

/**
 * @brief OLED清屏
 */
void oled_clear(void)
{
    // 清除显示缓冲区
    // 发送清屏命令
}

/**
 * @brief OLED显示字符串
 */
void oled_display_string(uint8_t x, uint8_t y, const char* str)
{
    // 在指定位置显示字符串
    // x: 列位置 (0-127)
    // y: 行位置 (0-7)
    printf("OLED显示: (%d,%d) %s\n", x, y, str);
}

/**
 * @brief OLED显示数字
 */
void oled_display_number(uint8_t x, uint8_t y, int32_t num)
{
    char buffer[16];
    snprintf(buffer, sizeof(buffer), "%d", num);
    oled_display_string(x, y, buffer);
}

/**
 * @brief OLED刷新显示
 */
void oled_refresh(void)
{
    // 将显示缓冲区内容发送到OLED
}

/**
 * @brief 蜂鸣器初始化
 */
void buzzer_init(void)
{
    // 配置PWM定时器用于蜂鸣器控制
    // GPIO42配置为PWM输出
    
    printf("蜂鸣器初始化完成\n");
}

/**
 * @brief 播放指定频率和时长的音调
 */
void buzzer_play_tone(uint16_t frequency, uint16_t duration)
{
    if (frequency == 0) {
        // 静音
        // 停止PWM输出
        delay_ms(duration);
        return;
    }
    
    // 设置PWM频率
    // uint32_t period = CPU_FREQUENCY_MHZ * 1000000 / frequency;
    // TIM_SetAutoreload(TIMx, period);
    // TIM_SetCompare1(TIMx, period / 2); // 50%占空比
    
    printf("蜂鸣器播放: %dHz, %dms\n", frequency, duration);
    
    delay_ms(duration);
    
    // 停止PWM输出
}

/**
 * @brief 播放旋律
 */
void buzzer_play_melody(melody_t melody)
{
    const uint16_t* notes = NULL;
    uint16_t note_duration = 200;
    
    switch (melody) {
        case MELODY_STARTUP:
            notes = startup_melody;
            note_duration = 300;
            break;
        case MELODY_HOURLY:
            notes = hourly_melody;
            note_duration = 500;
            break;
        case MELODY_WARNING:
            notes = warning_melody;
            note_duration = 150;
            break;
        case MELODY_ERROR:
            notes = error_melody;
            note_duration = 200;
            break;
        case MELODY_SHUTDOWN:
            notes = shutdown_melody;
            note_duration = 400;
            break;
        default:
            return;
    }
    
    for (int i = 0; notes[i] != 0 || i < 10; i++) {
        if (notes[i] == 0) break;
        buzzer_play_tone(notes[i], note_duration);
        delay_ms(50); // 音符间隔
    }
}

/**
 * @brief 播放警告音
 */
void buzzer_play_warning(void)
{
    buzzer_play_melody(MELODY_WARNING);
}

/**
 * @brief 播放错误音
 */
void buzzer_play_error(void)
{
    buzzer_play_melody(MELODY_ERROR);
}

/**
 * @brief LED初始化
 */
void led_init(void)
{
    // 配置LED引脚为输出
    // GPIO35 (红色), GPIO36 (绿色), GPIO41 (蓝色)
    
    // 初始状态全部关闭
    led_set_all(false);
    
    printf("LED指示灯初始化完成\n");
}

/**
 * @brief 设置LED颜色状态
 */
void led_set_color(led_color_t color, bool state)
{
    switch (color) {
        case LED_RED:
            // GPIO_WriteBit(GPIOX, GPIO_LED_RED, state ? Bit_SET : Bit_RESET);
            printf("红色LED: %s\n", state ? "开" : "关");
            break;
        case LED_GREEN:
            // GPIO_WriteBit(GPIOX, GPIO_LED_GREEN, state ? Bit_SET : Bit_RESET);
            printf("绿色LED: %s\n", state ? "开" : "关");
            break;
        case LED_BLUE:
            // GPIO_WriteBit(GPIOX, GPIO_LED_BLUE, state ? Bit_SET : Bit_RESET);
            printf("蓝色LED: %s\n", state ? "开" : "关");
            break;
        case LED_ALL:
            led_set_color(LED_RED, state);
            led_set_color(LED_GREEN, state);
            led_set_color(LED_BLUE, state);
            break;
    }
}

/**
 * @brief 设置所有LED状态
 */
void led_set_all(bool state)
{
    led_set_color(LED_ALL, state);
}

/**
 * @brief LED闪烁
 */
void led_blink(led_color_t color, uint16_t period)
{
    static uint32_t last_blink_time = 0;
    static bool blink_state = false;
    
    if (g_system_ticks - last_blink_time >= period) {
        blink_state = !blink_state;
        led_set_color(color, blink_state);
        last_blink_time = g_system_ticks;
    }
}

/**
 * @brief 按键初始化
 */
void button_init(void)
{
    // 配置按键引脚为输入，使能上拉电阻
    // GPIO56 (功能键), GPIO82 (校准键), GPIO83 (复位键)
    
    printf("按键初始化完成\n");
}

/**
 * @brief 检查按键是否按下
 */
bool button_is_pressed(button_t button)
{
    bool current_state = false;
    
    switch (button) {
        case BUTTON_FUNCTION:
            // current_state = !GPIO_ReadInputDataBit(GPIOX, GPIO_BUTTON_FUNC);
            break;
        case BUTTON_CALIBRATE:
            // current_state = !GPIO_ReadInputDataBit(GPIOX, GPIO_BUTTON_CALIB);
            break;
        case BUTTON_RESET:
            // current_state = !GPIO_ReadInputDataBit(GPIOX, GPIO_BUTTON_RESET);
            break;
    }
    
    // 简单的按键消抖
    static bool last_states[3] = {false};
    static uint32_t debounce_time[3] = {0};
    
    if (current_state != last_states[button]) {
        debounce_time[button] = g_system_ticks;
    }
    
    if ((g_system_ticks - debounce_time[button]) > 50) { // 50ms消抖
        if (current_state && !g_button_states[button]) {
            g_button_states[button] = true;
            g_button_press_time[button] = g_system_ticks;
            last_states[button] = current_state;
            return true;
        } else if (!current_state && g_button_states[button]) {
            g_button_states[button] = false;
        }
    }
    
    last_states[button] = current_state;
    return false;
}

/**
 * @brief 检查按键是否长按
 */
bool button_is_long_pressed(button_t button)
{
    if (g_button_states[button]) {
        return (g_system_ticks - g_button_press_time[button]) > 2000; // 2秒长按
    }
    return false;
}

/**
 * @brief 音频系统初始化
 */
void audio_init(void)
{
    // 初始化音频PWM输出
    // 配置GPIO25为PWM输出
    // 初始化音频放大器
    
    printf("音频系统初始化完成\n");
}

/**
 * @brief 播放TTS语音
 */
void audio_play_tts(const char* text)
{
    printf("TTS播放: %s\n", text);
    
    // 这里应该调用TTS引擎或发送到云端TTS服务
    // 简化实现：播放提示音代替
    buzzer_play_tone(1000, 500);
    
    delay_ms(strlen(text) * 100); // 模拟播放时间
}

/**
 * @brief 检查是否有语音输入
 */
bool audio_has_voice_input(void)
{
    // 检查麦克风输入
    // 简化实现：返回false
    return false;
}

/**
 * @brief 获取语音识别文本
 */
bool audio_get_voice_text(char* buffer, size_t buffer_size)
{
    // 语音识别实现
    // 简化实现：返回false
    return false;
}

/**
 * @brief WiFi模块初始化
 */
void wifi_init(void)
{
    // 初始化UART5用于ESP8266通信
    // 配置波特率115200
    // 发送AT命令初始化ESP8266
    
    printf("WiFi模块初始化完成\n");
}

/**
 * @brief WiFi连接
 */
bool wifi_connect(const char* ssid, const char* password)
{
    printf("连接WiFi: %s\n", ssid);
    
    // 发送AT+CWJAP命令连接WiFi
    // AT+CWJAP="ssid","password"
    
    // 简化实现：模拟连接成功
    delay_ms(5000);
    printf("WiFi连接成功\n");
    return true;
}

/**
 * @brief 检查WiFi连接状态
 */
bool wifi_is_connected(void)
{
    // 发送AT+CWJAP?查询连接状态
    // 简化实现：返回true
    return true;
}

/**
 * @brief 检查是否有WiFi消息
 */
bool wifi_has_message(void)
{
    // 检查UART接收缓冲区
    // 简化实现：返回false
    return false;
}

/**
 * @brief 接收WiFi消息
 */
bool wifi_receive_message(char* buffer, size_t buffer_size)
{
    // 从UART接收数据
    // 简化实现：返回false
    return false;
}

/**
 * @brief 发送WiFi消息
 */
bool wifi_send_message(const char* message)
{
    printf("WiFi发送: %s\n", message);
    // 通过UART发送数据
    return true;
}

/**
 * @brief 发送HTTP POST请求
 */
bool wifi_send_http_post(const char* url, const char* data)
{
    printf("HTTP POST: %s\n", url);
    printf("数据: %s\n", data);
    
    // 构建HTTP请求
    // AT+CIPSTART="TCP","server",80
    // AT+CIPSEND=length
    // POST /api HTTP/1.1...
    
    return true;
}

/**
 * @brief 接收HTTP响应
 */
bool wifi_receive_response(char* buffer, size_t buffer_size)
{
    // 接收HTTP响应数据
    // 简化实现：返回模拟响应
    strcpy(buffer, "HTTP响应数据");
    return true;
}

/**
 * @brief 发送响应
 */
void wifi_send_response(const char* response)
{
    printf("WiFi响应: %s\n", response);
}

/**
 * @brief RTC初始化
 */
void rtc_init(void)
{
    // 初始化RTC时钟
    // 配置LSE或LSI时钟源
    
    printf("RTC时钟初始化完成\n");
}

/**
 * @brief 获取RTC时间
 */
void rtc_get_time(rtc_time_t* time)
{
    // 从RTC读取时间
    // 简化实现：使用系统节拍模拟
    uint32_t total_seconds = g_system_ticks / 1000;
    
    time->second = total_seconds % 60;
    time->minute = (total_seconds / 60) % 60;
    time->hour = (total_seconds / 3600) % 24;
    time->day = 1;
    time->month = 1;
    time->year = 24; // 2024
}

/**
 * @brief 设置RTC时间
 */
void rtc_set_time(const rtc_time_t* time)
{
    printf("设置时间: %02d:%02d:%02d\n", time->hour, time->minute, time->second);
    // 设置RTC寄存器
}

/**
 * @brief 获取时间戳
 */
uint32_t rtc_get_timestamp(void)
{
    // 返回Unix时间戳
    return g_system_ticks / 1000 + 1640995200; // 2022-01-01基准
}

/**
 * @brief 数据存储初始化
 */
void storage_init(void)
{
    // 初始化Flash存储
    // 或者初始化外部EEPROM
    
    printf("数据存储初始化完成\n");
}

/**
 * @brief 保存会话数据
 */
bool storage_save_session_data(const void* data)
{
    printf("保存会话数据\n");
    // 写入Flash或EEPROM
    return true;
}

/**
 * @brief 加载会话数据
 */
bool storage_load_session_data(void* data)
{
    printf("加载会话数据\n");
    // 从Flash或EEPROM读取
    return true;
}

/**
 * @brief 清除所有数据
 */
bool storage_clear_all(void)
{
    printf("清除所有存储数据\n");
    // 擦除Flash扇区
    return true;
}

/**
 * @brief 进入睡眠模式
 */
void enter_sleep_mode(void)
{
    printf("进入睡眠模式\n");
    // 配置唤醒源
    // 进入低功耗模式
}

/**
 * @brief 进入深度睡眠
 */
void enter_deep_sleep(void)
{
    printf("进入深度睡眠\n");
    // 保存关键数据
    // 关闭外设
    // 进入深度睡眠模式
}

/**
 * @brief 系统软复位
 */
void system_soft_reset(void)
{
    printf("系统软复位\n");
    // NVIC_SystemReset();
}

/**
 * @brief 切换显示模式
 */
void toggle_display_mode(void)
{
    static uint8_t display_mode = 0;
    display_mode = (display_mode + 1) % 3;
    
    printf("切换显示模式: %d\n", display_mode);
}

/**
 * @brief 上传坐姿警告数据
 */
bool upload_posture_warning(float distance, int posture_state)
{
    char data[128];
    snprintf(data, sizeof(data),
            "{\"type\":\"warning\",\"distance\":%.1f,\"posture\":%d,\"timestamp\":%u}",
            distance, posture_state, rtc_get_timestamp());
    
    return wifi_send_http_post("/api/posture_warning", data);
}

/**
 * @brief 系统节拍中断处理函数
 */
void SysTick_Handler(void)
{
    g_system_ticks++;
}